ホッパーのインベントリをコマンドでいじる方法を考えてみた【マインクラフト】

スポンサーリンク

ようこそぷっこ村へ、ししゃもだよ。

(・∀・)ノ

最近、色々とコマンドのことを質問されるので、解決内容を残しといたらいいかなって思いました。今回は「ホッパーの真ん中のスロットに○○って名前がついたレッドストーンダストを、スコアボードの数だけ入れたい」っていうニッチな内容。ニッチさこそぷっこ村の正義なので張り切っていこう!!

アルゴリズム?的なものを考える

全体の流れを考えて整理してみると、

  1. 何かしらの行動をトリガーにして、
  2. 任意のホッパーのスロットを弄る

みたいな感じかな。雑……。

行動のトリガーを考える

1は動力を与える、もしくはタグによる検出になると思います。まぁデータパックなんでタグにしましょうか。タグはスコアボードを用意し、特定のアイテムを持った状態で使うことによって検出するのが楽です。例えば

/scoreboard objectives add Fire minecraft.used:minecraft.carrot_on_a_stick

/tag @a[nbt={SelectedItem:{tag:{ItemName:aaa}}}] add Hold_aaa
/execute if entity @a[tag=Hold_aaa,scores={Fire=1}] run function hogemoge

上記のようにすると常に監視できるよ。できれば空白行で2つの function に分けましょう。

ホッパーのスロットを動的に弄りたい

ホッパーのスロットを弄るのは /data merge で簡単にできます。nbt の内容も指定できるので、今回の場合は適してるかな。試しにホッパーの窪みに入って……、

/data merge block ~ ~ ~ {Items:[{Slot:2b,id:"minecraft:redstone",Count:1b,tag:{ItemName:aaa,display:{Name:'{"text":"aaa","color":"red","italic":false}'}}}]}
Minecrafterししゃもがマインクラフトのコマンドを解説する。今回はホッパーの指定スロットを弄る方法1

上記を実行するとホッパーの真ん中にアイテムができます。これを任意の数入れられたらオッケーなわけです。またホッパーの任意のスロット情報は /data get block で取得可能です。ただし、座標の指定が必要になるので、そこをどうするかです。

試しにさっき弄ったホッパーの窪みに入って以下のコマンドを実行してみると……、

/data get block ~ ~ ~ Items[{Slot:2b}].Count
Minecrafterししゃもがマインクラフトのコマンドを解説する。今回はホッパーの指定スロットを弄る方法2

:1b が帰ってきました。上記の Items[{Slot:2b}].Count はパスで、それぞれのエンティティや、ブロックエンティティに設定されています。これは、言わずもがなホッパーのスロット2(真ん中)に入っている個数で、ここのパスを指定して、スコアボードの値をぶち込めればいいわけです。

では、スコアボードの値をぶっこんでみましょう。スコアボードの値の出し入れは execute store result を使います。

/scoreboard objectives add Count dummy
/scoreboard players set @s Count 10

/execute store result block ~ ~ ~ Items[{Slot:2b}].Count int 1 run scoreboard players get @p Count

とすると、真ん中の個数が10個になっていると思います。

Minecrafterししゃもがマインクラフトのコマンドを解説する。今回はホッパーの指定スロットを弄る方法3

これでホッパーとスコアボードをリンクさせる方法はあらかたできマンタ!!

さて、プレイヤーの裁量で任意に置ける場合、何かしらの方法で座標を取得する方法が必要です。ソフトコーディングっぽいことがしたい場合、エンティティと組み合わせる必要があります。今回はタグ付けした額縁を使うことにしますが、別にアマスタでもいいし、後光が差したおっさん立たせといてもいいです。タグ付けは各自条件を決めて実行してもらうとして、ここでは単に tag だけにします。特定のタグを持ったアイテムを入れている場合のみ反応するとかにした方がより安全(というかそうしないとどっかでバグること山の如し)です。

またホッパー弄りのコマンド群は function ファイルを別で用意した方がいいと思います。

/execute if entity @a[tag=Hold_aaa,scores={Fire=1}] run function moge

/execute as @e[type=minecraft:item_frame,tag=!bbb,sort=nearest,limit=1] run tag @s add bbb
/execute as @e[type=minecraft:item_frame,tag=bbb] at @s if block ~ ~-0.5 ~ minecraft:hopper{Items:[]} run data merge block ~ ~-0.5 ~ {Items:[{Slot:2b,id:"minecraft:redstone",Count:1b,tag:{ItemName:aaa,display:{Name:'{"text":"aaa","color":"red","italic":false}'}}}]}
/execute at @e[type=minecraft:item_frame,tag=bbb] if block ~ ~-0.5 ~ minecraft:hopper{Items:[{Slot:2b,id:"minecraft:redstone",Count:1b,tag:{ItemName:aaa,display:{Name:'{"text":"aaa","color":"red","italic":false}'}}}]} store result block ~ ~-0.5 ~ Items[{Slot:2b}].Count int 1 run scoreboard players get @p Count
/execute as @e[type=minecraft:item_frame,tag=bbb,sort=nearest,limit=1] run tag @s remove bbb

1行目はメイン側の処理で、条件を満たした場合3行目以降が実行されるとします。タグ付けの際はもう少し厳密に向きの指定なども加えた方がいいかもね!!これでホッパーの中身が変わってるはずなので、最後にプレイヤーのタグやスコアボードをリセットすればオッケー

/scoreboard players reset @a Count
/scoreboard players reset @a Fire

などなど

まとめると

以上までをまとめると、それぞれの function は

scoreboard objectives add Fire minecraft.used:minecraft.carrot_on_a_stick
scoreboard objectives add Count dummy
tag @a[nbt={SelectedItem:{tag:{ItemName:aaa}}}] add Hold_aaa
execute if entity @a[tag=Hold_aaa,scores={Fire=1}] run function hogemoge
tag @a[nbt=!{SelectedItem:{tag:{ItemName:aaa}}}] remove Hold_aaa
execute as @e[type=minecraft:item_frame,tag=!bbb,sort=nearest,limit=1] run tag @s add bbb
execute as @e[type=minecraft:item_frame,tag=bbb] at @s if block ~ ~-0.5 ~ minecraft:hopper{Items:[]} run data merge block ~ ~-0.5 ~ {Items:[{Slot:2b,id:"minecraft:redstone",Count:1b,tag:{ItemName:aaa,display:{Name:'{"text":"aaa","color":"red","italic":false}'}}}]}
execute at @e[type=minecraft:item_frame,tag=bbb] if block ~ ~-0.5 ~ minecraft:hopper{Items:[{Slot:2b,id:"minecraft:redstone",Count:1b,tag:{ItemName:aaa,display:{Name:'{"text":"aaa","color":"red","italic":false}'}}}]} store result block ~ ~-0.5 ~ Items[{Slot:2b}].Count int 1 run scoreboard players get @p Count
execute as @e[type=minecraft:item_frame,tag=bbb,sort=nearest,limit=1] run tag @s remove bbb

みたいな感じになる。もちろん、これだと Count の値を決める方法がないのでまだまだ付け加える必要があります。そこんとこは各自のやりたいことに合わせて決めてね。

今回のコマンドで大事なのは Items[{Slot:2b}].Count などのパス指定がわかれば、応用が効くってことと、execute score result がスコアボードとのリンクにつかいやすいってこと

なんか堅苦しくなって、ぷっこ村に似つかわしくない気もするけど観光用のデータパック開発も今後のししゃもの課題なので少しづつ混ぜていくよ。

他にも「こんなんやりたいけどわからんから解説してくれ」みたいなのがあったらリクエストオナシャス。できるだけニッチに解説を繰り広げていきたいよ。
それではこの辺で、お帰りの際はお気をつけて~(・∀・)ノシ

コメント